using System;
using System.Collections.Generic;
using System.Text;

namespace TVDesigner.Generator.Components
{
    public class ProjectXlet
    {
        private string _Name;
        private List<Screen> _Screens;
        private Screen _StartPoint;
        private Dictionary<string, string> _StaticScreenStringName;

        public Dictionary<string, string> StaticScreenStringName
        {
            get { return _StaticScreenStringName; }
        }
	
        public ProjectXlet(string name, ParseElements elements)
        {
            _Name = name;
            _StartPoint = elements.StartPoint;
            _Screens = elements.Screens;
            _StaticScreenStringName = new Dictionary<string, string>();
        }

        public string NameStartedWithUpperCase
        {
            get
            {
                char c = (((string)_Name.Clone()).ToUpper())[0];
                return
                    string.Concat(c, _Name.Substring(1, _Name.Length - 1));
            }
        } 

        public string DeclareClass(string package)
        {
            StringBuilder sb = new StringBuilder();

            //package
            if (package != null && !package.Equals(string.Empty))
            {
                sb.Append("package ").Append(package).Append(";\n\n");
            }

            //imports.
            sb.Append(@"
import javax.media.Player;
import javax.tv.media.AWTVideoSize;
import javax.tv.media.AWTVideoSizeControl;
import javax.tv.service.selection.ServiceContentHandler;
import javax.tv.service.selection.ServiceContextFactory;
import javax.tv.xlet.Xlet;
import javax.tv.xlet.XletContext;
import javax.tv.xlet.XletStateChangeException;
import org.havi.ui.HContainer;
import org.havi.ui.HScene;
import org.havi.ui.HSceneFactory;
import org.havi.ui.HScreen;
import java.awt.Rectangle;
import java.awt.Color;

");

            sb.Append("\n");

            //class declaration.
            sb.Append("public class ").Append(NameStartedWithUpperCase).Append(" extends HContainer implements Xlet {\n");
            sb.Append("\n");

            //atributes
            LoadAtributesDeclaration(sb);
            sb.Append("\n");

            //constructors.
            LoadConstructor(sb);
            sb.Append("\n");

            //methods.
            LoadMethods(sb);
            sb.Append("\n");

            sb.Append("}\n");

            return sb.ToString();
        }

        private void LoadAtributesDeclaration(StringBuilder sb)
        {
            LoadStaticScreenNumerationAtributes(sb);
            sb.Append("\n");
            sb.Append("\tprotected XletContext context;\n");
            sb.Append("\tprotected HScene scene;\n");
            sb.Append("\tprotected TVDesignerScreen[] screens = new TVDesignerScreen[").Append(_Screens.Count).Append("];\n");
            sb.Append("\tprotected TVDesignerScreen currentScreen;\n");
			//Alterei aki Thiago
			sb.Append("\tprotected TVDesignerScreen previousScreen;\n");
            sb.Append("\tprotected TVDesignerKeyListener listener;\n");

            //TODO - acrescentar os outros atributos.
          
        }

        private void LoadStaticScreenNumerationAtributes(StringBuilder sb)
        {
            int count = 0;
            foreach (Screen screen in _Screens)
            {
                sb.Append("\tpublic static final int ").Append(screen.Name.ToUpper()).Append(" = ").Append(count++).Append(";\n");
                _StaticScreenStringName.Add(screen.Name, screen.Name.ToUpper());
            }
        }

        private void LoadConstructor(StringBuilder sb)
        {
            //throw new Exception("The method or operation is not implemented.");
        }

        private void LoadMethods(StringBuilder sb)
        {
            this.LoadInitMethod(sb);
            sb.Append("\n");
            this.LoadStartMethod(sb);
            sb.Append("\n");
            this.LoadInitXletMethod(sb);
            sb.Append("\n");
            this.LoadDestroyXletMethod(sb);
            sb.Append("\n");
            this.LoadPauseXletMethod(sb);
            sb.Append("\n");
            this.LoadSetCurrentScreen(sb);
            sb.Append("\n");
            this.LoadResizeMethod(sb);
            sb.Append("\n");
            sb.Append("\n");
            //this.LoadDeclareKeyListener(sb);
            sb.Append("\n");
            this.LoadGetListenerMethod(sb);
            sb.Append("\n");
            this.LoadGetCurrentScreenMethod(sb);
            sb.Append("\n");
        }

      /*  private void LoadDeclareKeyListener(StringBuilder sb)
        {
            sb.Append(@"
    class TVDesignerKeyListener implements org.havi.ui.event.HKeyListener {

        private ").Append(this.NameStartedWithUpperCase).Append(@" xlet;
        
        public TVDesignerKeyListener(").Append(this.NameStartedWithUpperCase).Append(@" xlet){
            this.xlet = xlet;
        }
        		
	    public void keyTyped(java.awt.event.KeyEvent arg0) {}
	    public void keyReleased(java.awt.event.KeyEvent arg0) {}
	    public void keyPressed(java.awt.event.KeyEvent event) {
		    if (this.xlet.getCurrentScreen() == null) 
			    return;
            
		    this.xlet.getCurrentScreen().keyEvent(event);
            System.out.println(").Append("\"KEY_EVENT\"").Append(@");
            repaint();
	    }
    }");
        }*/

        private void LoadSetCurrentScreen(StringBuilder sb)
        {
			sb.Append("\tpublic void setCurrentScreen(int screen) {\n");
			//Coloquei Thiago
			sb.Append("\t\tthis.previousScreen = this.currentScreen;\n");

			sb.Append("\t\tthis.setCurrentScreen(this.screens[screen]);\n");
			sb.Append("\t}\n");
			sb.Append("\n\n");
            sb.Append("\tpublic void setCurrentScreen(TVDesignerScreen newCurrentScreen) {\n");
            sb.Append("\t\tif (this.currentScreen != null) {\n");
            sb.Append("\t\t\t((org.havi.ui.HContainer)this.currentScreen).setVisible(false);\n");
            sb.Append("\t\t}\n\n");
            sb.Append("\t\tthis.currentScreen = newCurrentScreen;\n");
            sb.Append("\t\t((org.havi.ui.HContainer)this.currentScreen).setVisible(true);\n");
            sb.Append("\t}\n");
			sb.Append("\n\n");

			sb.Append("\tpublic TVDesignerScreen getPreviousScreen() {\n");
			sb.Append("\t\treturn this.previousScreen;\n");
			sb.Append("\t}\n");
        }

        private void LoadStartMethod(StringBuilder sb)
        {
            sb.Append("\tpublic void startXlet() throws XletStateChangeException {\n");
            sb.Append("\t\tthis.init();\n\n");
            this.LoadKeyListener(sb);

            int count = 0;
            int startPointIndex = -1;
            foreach (Screen screen in _Screens)
            {
                sb.Append("\t\tthis.screens[").Append(count).Append("] = new ").Append(screen.NameStartedWithUpperCase).Append("(this);\n");
                if (screen.Equals(_StartPoint))
                {
                    startPointIndex = count;
                }
                count++;
            }
            sb.Append("\n");

            count = 0;
            /*foreach (Screen screen in _Screens)
            {
                sb.Append("\t\tthis.screens[").Append(count).Append("].setXlet(this);\n");
                count++;
            }
            sb.Append("\n");*/

            count = 0;
            foreach (Screen screen in _Screens)
            {
                sb.Append("\t\tthis.add(").Append("((org.havi.ui.HContainer)screens[").Append(count).Append("]));\n");
                count++;
            }

            sb.Append("\n");

            sb.Append("\t\tthis.setCurrentScreen(this.screens[").Append(startPointIndex).Append("]);\n");

            sb.Append("\n");
            
            sb.Append("\n");
            sb.Append("\t}\n");
        }

        private void LoadKeyListener(StringBuilder sb)
        {
            //sb.Append("\t\tthis.addKeyListener(new TVDesignerKeyListener());");
            sb.Append("\t\tthis.listener = new TVDesignerKeyListener(this);\n");
            
        }

        private void LoadPauseXletMethod(StringBuilder sb)
        {
            sb.Append("\tpublic void pauseXlet() {\n");
            sb.Append("\t\t// TODO Auto-generated method stub\n");
            sb.Append("\t}\n");
        }

        private void LoadDestroyXletMethod(StringBuilder sb)
        {
            sb.Append("\tpublic void destroyXlet(boolean arg0) throws XletStateChangeException {\n");
		    sb.Append("\t\t// TODO Auto-generated method stub\n");
            sb.Append("\t}\n");
        }

        private void LoadInitXletMethod(StringBuilder sb)
        {
            sb.Append("\tpublic void initXlet(XletContext arg0) throws XletStateChangeException {\n");
            sb.Append("\t\tthis.context = arg0;\n");
            sb.Append("\t}\n");
        }

        private void LoadGetListenerMethod(StringBuilder sb)
        {
            sb.Append("\tpublic TVDesignerKeyListener getListener() {\n");
            sb.Append("\t\treturn this.listener;\n");
            sb.Append("\t}\n");
        }

        private void LoadGetCurrentScreenMethod(StringBuilder sb)
        {
            sb.Append("\tpublic TVDesignerScreen getCurrentScreen() {\n");
            sb.Append("\t\treturn this.currentScreen;\n");
            sb.Append("\t}\n");
        }

        private void LoadInitMethod(StringBuilder sb)
        {
            sb.Append("\tprotected void init() {\n");

            sb.Append(@"
        this.scene = HSceneFactory.getInstance().getFullScreenScene(
        HScreen.getDefaultHScreen().getDefaultHGraphicsDevice());

        this.scene.setLayout(null);
        this.scene.setLocation(0, 0);

        Rectangle rect = scene.getBounds();
		System.out.println(rect.toString());
        this.setBounds(rect);

        this.setVisible(true);
        this.setBackground(Color.black);

		this.scene.add(this);
        this.scene.setVisible(true);

		this.requestFocus();
        
");
            sb.Append("\t}\n");
        }


        private void LoadResizeMethod(StringBuilder sb)
        {
            sb.Append(@"
    /**
	 * Resize the video.
	 * 
	 * @param size - AWTVideoSize (currentSize, finalSize)
	 */
	public void resize(AWTVideoSize size) {			 
		ServiceContextFactory serviceContextFactory = null;			
		javax.tv.service.selection.ServiceContext serviceContext = null;
				
		try {
			serviceContextFactory = ServiceContextFactory.getInstance();				
			serviceContext = serviceContextFactory.getServiceContext(context);	
		}
		catch (Exception ex) {				
			ex.printStackTrace();				
		}
				
		if (serviceContext != null) {			
			ServiceContentHandler[] serviceContentHandler = serviceContext.getServiceContentHandlers();
			Player player = null;
			
			if (serviceContentHandler.length > 0) {				
				player = (Player) serviceContentHandler[0];		
			}
 
			if (player != null) {				
				AWTVideoSizeControl awtVideoSizeControl = (AWTVideoSizeControl) player.getControl(").Append("\"javax.tv.media.AWTVideoSizeControl\");\n");
				sb.Append(@"
                awtVideoSizeControl.setSize(size);
			}
		}
	}");
        }




    }
}
